package org.example.study4;
/**
 * 为方法加锁，解决线程安全问题，使用synchronized修饰 -- 方法级别锁
 */
public class Demo_401 {
    public static void main(String[] args) throws InterruptedException {
        // 初始化累加对象
        Counter401 counter = new Counter401(); // 创建 Counter401 实例

        // 创建两个线程对同一个变量进行累加
        Thread t1 = new Thread(() -> {
            // 线程1执行5万次累加
            for (int i = 0; i < 50000; i++) {
                counter.increase(); // 调用同步方法
            }
        });

        Thread t2 = new Thread(() -> {
            // 线程2执行5万次累加
            for (int i = 0; i < 50000; i++) {
                counter.increase(); // 调用同步方法
            }
        });

        // 启动线程
        t1.start(); // 启动线程1
        t2.start(); // 启动线程2

        // 等待线程执行完成
        t1.join();  // 主线程等待线程1结束
        t2.join();  // 主线程等待线程2结束

        // 查看运行结果
        System.out.println("count = " + counter.count); // 输出最终结果
    }
}


class Counter401 {
    public int count = 0; // 共享变量，初始值为0

    /**
     * 累加方法（同步方法）
     */
    public synchronized void increase() { // 使用 synchronized 为方法加锁
        count++; // 原子操作（在同步保护下）
    }
}



/*

运行：
count = 100000

代码简述：使用 synchronized 为方法加锁。t1先获取到了锁，执行方法，方法执行完成之后其他线程再获取锁
这样的情况是一个单线程运行的状态。是把多线程转成了单线程，从而解决线程安全问题




改进解决的问题
1. 线程安全性：
synchronized 通过内置锁（对象锁）保证方法原子性，避免多个线程同时修改 count。
解决原代码中的竞态条件和数据不一致问题。

2. 原子性保证：
count++ 操作原本是非原子的（读取→修改→写入），现在在同步方法中执行，三步操作被绑定为原子操作。

3. 同步锁机制：
当线程调用 synchronized 方法时，会获取当前对象（counter）的锁。
其他线程必须等待锁释放后才能执行该方法，从而避免并发冲突。



总结：锁概念：线程A拿到了锁，别的线程如果执行被锁住的代码，必须要等到线程A释放锁，如果线程A没有释放锁，那么别的线程只能阻塞等待，这个状态就是BLOCK
简易过程：先拿锁-》执行代码-》释放锁-》下一个线程再拿锁*/
